using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using YouVisio.Silverlight.TextDiff;

namespace YouVisio.Silverlight.TextDiffTests
{
    [TestClass]
    public class StringHashInfo_Tests : BaseTestClass
    {
        [TestMethod]
        public void Can_Create_StringHashInfo_For_Lines()
        {
            var sb = new StringBuilder();
            foreach (var e in Enumerable.Range(0, 10))
                sb.AppendLine(SR.LoremIpsum);
            var source = sb.ToString();

            var info = StringHashInfo.CreateForLines(source, source);

            Assert.IsNotNull(info);
            Assert.AreEqual(45, info.Unique.Count);
            Assert.AreEqual(491, info.LeftListHashes.Count);
            Assert.AreEqual(491, info.RightListHashes.Count);
        }

        [TestMethod]
        public void StringHashInfo_Can_Fold_Text_Parts_Case_1()
        {
            var info = StringHashInfo.CreateForLines("aaa\rbbb\nccc", "aaa\r\nsss\nbbb\nccc");
            var diffList = new DiffPartsList { { Operation.Equal, 1 }, { Operation.Insert, 1 }, { Operation.Equal, 2 } };
            var result = info.FoldTextParts(new List<TextPart>(), diffList, (list, tp) => { list.Add(tp); return list; });

            Assert.AreEqual(NoSpace(@"
                    aaa|aaa
                    ___|sss
                    bbb|bbb
                    ccc|ccc"), PrintTextParts(result, "___"));
        }

        [TestMethod]
        public void StringHashInfo_Can_Fold_Text_Parts_Case_2()
        {
            var info = StringHashInfo.CreateForLines("aaa\rsss\nbbb\nccc", "aaa\r\nbbb\nccc");
            var diffList = new DiffPartsList { { Operation.Equal, 1 }, { Operation.Delete, 1 }, { Operation.Equal, 2 } };
            var result = info.FoldTextParts(new List<TextPart>(), diffList, (list, tp) => { list.Add(tp); return list; });

            Assert.AreEqual(NoSpace(@"
                    aaa|aaa
                    sss|___
                    bbb|bbb
                    ccc|ccc"), PrintTextParts(result, "___"));
        }

        [TestMethod]
        public void StringHashInfo_Can_Fold_Text_Parts_Case_3()
        {
            var info = StringHashInfo.CreateForLines("aaa\rsss\nbbb\nccc", "aaa\r\nbbb\nccc\nzzz");
            var diffList = new DiffPartsList { { Operation.Equal, 1 }, { Operation.Delete, 1 }, { Operation.Equal, 2 }, { Operation.Insert, 1 } };
            var result = info.FoldTextParts(new List<TextPart>(), diffList, (list, tp) => { list.Add(tp); return list; });

            //WriteLine(PrintTextParts(result, "___"));

            Assert.AreEqual(NoSpace(@"
                    aaa|aaa
                    sss|___
                    bbb|bbb
                    ccc|ccc
                    ___|zzz"), PrintTextParts(result, "___"));
        }

        private static string PrintTextParts(IEnumerable<TextPart> parts, string empty)
        {
            var sb = new StringBuilder();
            foreach (var textPart in parts)
            {
                var numLines = textPart.Initial == null ? textPart.Changed.Length : textPart.Initial.Length;
                for (var i = 0; i < numLines; i++)
                {
                    var a = textPart.Initial == null ? empty : textPart.Initial[i];
                    var b = textPart.Changed == null ? empty : textPart.Changed[i];
                    sb.AppendLine(a + "|" + b);
                }
            }
            return NoSpace(sb.ToString());
        }
        private static string NoSpace(string str)
        {
            return str.Replace(" ", "").Trim();
        }
    }
}